/*******************************************************************************
 * Copyright 2009, 2010 Innovation Gate GmbH. All Rights Reserved.
 * 
 * This file is part of the OpenWGA server platform.
 * 
 * OpenWGA is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * In addition, a special exception is granted by the copyright holders
 * of OpenWGA called "OpenWGA plugin exception". You should have received
 * a copy of this exception along with OpenWGA in file COPYING.
 * If not, see <http://www.openwga.com/gpl-plugin-exception>.
 * 
 * OpenWGA is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with OpenWGA in file COPYING.
 * If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/

package de.innovationgate.wgpublisher;

import de.innovationgate.utils.security.HashedPassword;
import de.innovationgate.utils.security.HashingException;
import de.innovationgate.utils.security.HashingService;
import de.innovationgate.webgate.api.WGException;
import de.innovationgate.wga.modules.ModuleRegistry;
import de.innovationgate.wga.modules.RegistryAwareModule;
import de.innovationgate.wga.server.api.WGA;

/**
 * Tool object use hashed password values as stored by <tml:input type="hashedpassword"/>.
 * These values contain a hashed password plus a hashing scheme identifier. Use this service to create, read and check those values against cleartext passwords.
 * On creating hashed passwords this object automatically uses the hashing algorithm that is configured as default for the current OpenWGA runtime. It however can read and check all hashes whose hashing scheme is known to the runtime.
 */
public class HashedPasswordService implements RegistryAwareModule {

    private ModuleRegistry _reg;
    private WGACore _core;

    @Override
    public void injectRegistry(ModuleRegistry registry) {
        _reg = registry;
        _core = (WGACore) _reg.getContextObjects().get(WGACore.class);
    }
    
    /**
     * Creates a new hashed password from a cleartext password and a salt value
     * @param cleartextPassword The cleartext password
     * @param salt The salt, generated by {@link #generateSalt()}
     * @return The hashed password. Use {@link HashedPassword#toString()} for the storable string representation.
     * @throws HashingException
     * @throws WGException
     */
    public HashedPassword create(String cleartextPassword, Object salt) throws HashingException, WGException {
        HashingService hashingService = WGA.get(_core).service(HashingService.class);
        HashedPassword hashedPwd = HashedPassword.create(cleartextPassword, hashingService, salt);
        return hashedPwd;
    }
    
    /**
     * Reads a stored hashed password
     * @param hashedPassword The stored hashed password string
     * @return The hashed password. Use {@link #checkEqual(HashedPassword, String)} to check it against a cleartext password for equality
     */
    public HashedPassword read(String hashedPassword) {
        return new HashedPassword(hashedPassword);
    }
    
    /**
     * Generates a salt value to be used with {@link #create(String, Object)} on hashed password creation
     * @throws HashingException
     * @throws WGException
     */
    public Object generateSalt() throws HashingException, WGException {
        HashingService hashingService = WGA.get(_core).service(HashingService.class);
        return hashingService.generateSalt();
    }
    
    /**
     * Checks if a hashed password and a cleartext password are equal
     * @param hashedPassword The hashed password, read via {@link #read(String)} or created via {@link #create(String, Object)}
     * @param cleartextPassword The cleartext password to check
     * @return true if the hashed password originates from the cleartext password
     * @throws HashingException
     */
    public boolean checkEqual(HashedPassword hashedPassword, String cleartextPassword) throws HashingException {
        return hashedPassword.check(cleartextPassword, _reg);
    }

}
